package com.asurplus.weixin.utils;

import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.asurplus.common.redis.RedisConst;
import com.asurplus.common.redis.RedisUtil;
import com.asurplus.common.utils.R;
import com.asurplus.weixin.vo.ClickButton;
import com.asurplus.weixin.vo.ComplexButton;
import com.asurplus.weixin.vo.ViewButton;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.List;

/**
 * 微信公众号的工具类
 */
@Component
@Slf4j
public class WeiXinUtils {

    @Autowired
    private RedisUtil redisUtil;

    @Value("${weixin.appid}")
    private String appid;
    @Value("${weixin.appsecret}")
    private String appsecret;

    /**
     * 获取微信access_token
     *
     * @return access_token，一般两个小时过期
     */
    public String getAccessToken() {
        Object object = redisUtil.get(RedisConst.Key.WEIXIN_ACCESS_TOKEN);
        if (null != object) {
            return String.valueOf(object);
        }
        String httpRes = HttpUtil.get(WeiXinConst.ACCESS_TOKEN_GET.replace("APPID", appid).replace("APPSECRET", appsecret));
        JSONObject jsonObject = JSONObject.parseObject(httpRes);
        String accessToken = jsonObject.getString("access_token");
        if (StringUtils.isBlank(accessToken)) {
            log.error("获取access_token失败");
            return null;
        }
        // 存入redis，少存200秒，早一点刷新
        redisUtil.set(RedisConst.Key.WEIXIN_ACCESS_TOKEN, accessToken, 7000);
        log.info("获取access_token成功：{}", accessToken);
        return accessToken;
    }

    /**
     * 获取微信服务器IP地址
     *
     * @return ["127.0.0.1", "127.0.0.2", "101.226.103.0/25"]
     */
    public List<String> getCallbackIp() {
        String httpRes = HttpUtil.get(WeiXinConst.CALLBACK_IP_GET.replace("ACCESS_TOKEN", getAccessToken()));
        JSONObject jsonObject = JSONObject.parseObject(httpRes);
        if (StringUtils.isBlank(jsonObject.getString("ip_list"))) {
            log.error("获取微信服务器IP地址失败");
            return null;
        }
        JSONArray ipList = JSONArray.parseArray(jsonObject.getString("ip_list"));
        log.error("获取微信服务器IP地址成功，{}", ipList.toJSONString());
        return ipList.toJavaList(String.class);
    }

    /**
     * 创建菜单
     *
     * @return
     */
    public R createMenu() {
        // 菜单组
        JSONArray jsonArray = new JSONArray();
        // 一级菜单
        ClickButton clickButton = new ClickButton();
        clickButton.setName("最新回复");
        clickButton.setKey("V1001_TODAY_MUSIC");
        clickButton.setType("click");
        jsonArray.add(clickButton);
        // 多级菜单
        ComplexButton complexButton = new ComplexButton();
        // 一级
        complexButton.setName("个人中心");
        // 二级
        ViewButton[] viewButtons = new ViewButton[2];
        ViewButton viewButton = new ViewButton();
        viewButton.setName("个人信息");
        viewButton.setType("view");
        viewButton.setUrl("http://www.baidu.com/");
        viewButtons[0] = viewButton;
        viewButton = new ViewButton();
        viewButton.setName("我的卡包");
        viewButton.setType("view");
        viewButton.setUrl("https://www.jd.com/");
        viewButtons[1] = viewButton;
        complexButton.setSub_button(viewButtons);
        jsonArray.add(complexButton);
        JSONObject param = new JSONObject();
        param.put("button", jsonArray);
        String httpRes = HttpUtil.post(WeiXinConst.CUSTOM_MENU_CREATE.replace("ACCESS_TOKEN", getAccessToken()), param.toJSONString());
        param = JSONObject.parseObject(httpRes);
        if ("0".equals(param.getString("errcode"))) {
            log.info("自定义菜单创建成功，{}", param.toJSONString());
            return R.ok("创建菜单成功");
        }
        log.error("自定义菜单创建失败");
        return R.no("创建菜单失败");
    }

    /**
     * 发送文本消息
     *
     * @param openId
     * @param message
     * @return
     */
    public R sentTextMessage(String openId, String message) {
        if (StringUtils.isBlank(openId)) {
            return R.no("用户信息不能为空");
        }
        if (StringUtils.isBlank(message)) {
            return R.no("不能发送空的消息");
        }
        JSONObject param = new JSONObject();
        param.put("touser", openId);
        // 消息类型
        param.put("msgtype", "text");
        // 消息内容
        JSONObject data = new JSONObject();
        data.put("content", message);
        param.put("text", data);
        String httpRes = HttpUtil.post(WeiXinConst.TEXT_MESSAGE_SEND.replace("ACCESS_TOKEN", getAccessToken()), param.toJSONString());
        JSONObject jsonObject = JSONObject.parseObject(httpRes);
        if ("0".equals(jsonObject.getString("errcode"))) {
            log.info("消息发送成功，{}", jsonObject.toJSONString());
            return R.ok("消息发送成功", jsonObject);
        }
        log.error("消息发送失败");
        return R.no("消息发送失败");
    }

    /**
     * 发送模板消息
     *
     * @param openId
     * @param templateId
     * @param message
     * @return
     */
    public R sentTemplateMessage(String openId, String templateId, String message) {
        if (StringUtils.isBlank(openId)) {
            return R.no("用户信息不能为空");
        }
        if (StringUtils.isBlank(message)) {
            return R.no("不能发送空的消息");
        }
        JSONObject param = new JSONObject();
        param.put("touser", openId);
        // 模板id
        param.put("template_id", templateId);
        /**
         * TODO 模板消息数据组装
         */
        String httpRes = HttpUtil.post(WeiXinConst.TEMPLATE_MESSAGE_SEND.replace("ACCESS_TOKEN", getAccessToken()), param.toJSONString());
        JSONObject jsonObject = JSONObject.parseObject(httpRes);
        if ("0".equals(jsonObject.getString("errcode"))) {
            log.info("消息发送成功，{}", jsonObject.toJSONString());
            return R.ok("消息发送成功", jsonObject);
        }
        log.error("消息发送失败");
        return R.no("消息发送失败");
    }

    /**
     * 获取用户信息
     *
     * @param openId
     * @return
     */
    public R getUserInfo(String openId) {
        if (StringUtils.isBlank(openId)) {
            return R.no("用户信息为空");
        }
        String httpRes = HttpUtil.get(WeiXinConst.USER_INFO_GET.replace("ACCESS_TOKEN", getAccessToken()).replace("OPENID", openId));
        JSONObject jsonObject = JSONObject.parseObject(httpRes);
        if (StringUtils.isBlank(jsonObject.getString("openid"))) {
            log.error("获取用户信息失败");
            return R.no("获取用户信息失败");
        }
        log.info("获取用户信息成功，{}", jsonObject.toJSONString());
        return R.ok(jsonObject);
    }

}
